package kgame5.pbe.atlantic.manager {
	import kgame5.kutil.T;
	import kgame5.pbe.atlantic.vo.EntityVO;

	import flash.utils.Dictionary;
	import kgame5.pbe.atlantic.vo.EntityMessageVO;
	import kgame5.pbe.engine.PBE;
	import kgame5.pbe.atlantic.comp.IEntityCompFacade;

	/**
	 * @author max
	 * 2010-12-13
	 * PBE的一个manager,这个主要是提供fsm内的GState来查找游戏内其他物体之用
	 * 不用PBE默认的nameManager.PBGroup体系来查询，一是由于性能，二是考虑这个是只读（算是标志一下）
	 * 
	 * 另外，用PBE.senseWorld和DataComp是为了onAdd和onRemove的时候方便操作
	 * 
	 * 如果实体间要通信，可以通过这个做,应为这样最简洁，引擎内置实体间发送消息，消息的接收者是IEntityCompFacade
	 */
	public class SenseWorld {

		private var dict_all : Dictionary;//全体
	
		//--发送事件用的,也是SenceWorld的一部分--
		//根据cateID分类，元素是dict[entID]=Entity
		private var dict_byCateID : Dictionary;//dict[cateID]=dict[id]<Entity>
		//根据typeID分类的,元素是dict[entID]=Entity
		private var dict_byTypeID : Dictionary;//dict[typeID]=dict[id]<Entity>
		
		public function SenseWorld(){
			clear();
		}
		
		//=========清理一下=========
		public function start():void{
			dict_all=new Dictionary();//全体
			 
			dict_byCateID=new Dictionary();
		
			dict_byTypeID=new Dictionary();
			
			dict_fastEntityFacadeCompMapping=new Dictionary();
		}
		
		public function clear():void{
			dict_all=null;//全体
			 
			dict_byCateID=null;
		
			dict_byTypeID=null;
			
			dict_fastEntityFacadeCompMapping=null;
		}
		
		//===================读取==================
		//返回某个大类的列表。比如坦克类，炮弹类
		
		public function getVOListByCateID(cateID : String) : Dictionary {
			return dict_byCateID[cateID];
		}

		//返回某个特定类的列表.好像用处不大.!想不出用处的暂时不实现
		public function getVOListByTypeID(typeID : String) : Dictionary {
			return dict_byTypeID[typeID];
		}

		public function getVOList() : Dictionary {
			return dict_all;
		}

		public function getVOByID(id : String) : EntityVO {
			return dict_all[id] as EntityVO;
		}

		//===================增加删除之类的==================
		public function add(vo : EntityVO) : void {
			//T.p("SenseWorld.add",vo.id);
			if(dict_all[vo.id] != null) {
				throw new Error("此id已被使用！" + vo.id);
			}
			//-总类表中添加
			dict_all[vo.id] = vo;
		
			//-数据读取
			var cateID : String = vo.cateID;
			var dict_cate : Dictionary = dict_byCateID[cateID];//按类分
			if(dict_cate == null) {
				dict_cate = new Dictionary();
				dict_byCateID[cateID] = dict_cate;
			}
			dict_cate[vo.id] = vo;
		
			//-
			var typeID : String = vo.typeID;
			var dict_type : Dictionary = dict_byTypeID[typeID];//按类分
			if(dict_type == null) {
				dict_type = new Dictionary();
				dict_byTypeID[typeID] = dict_type;
			}
			dict_type[vo.id] = vo;
		}

		

		//返回是否删除成功
		public function remove(id : String) : void {
		
			var vo : EntityVO = getVOByID(id);
			if(vo == null) {
				return ;
			}
		
			//总列表中删除
			delete dict_all[id];
		
		
		
			//-数据读取
			var dict_cate : Dictionary = dict_byCateID[vo.cateID];//按类分
			if(dict_cate != null) {
				delete dict_cate[vo.id];
			}
		
			//
			var dict_type : Dictionary = dict_byTypeID[vo.typeID];//按类分
			if(dict_type != null) {
				delete dict_type[vo.id];
			}
		}
		
		//=================消息发送=================
		//发送实体到实体的消息，可以发送到全体，大类，小类，某个
		public function sendEntityToEntityMessage(mvo:EntityMessageVO):void{
			
			//T.p("sendEntityToEntityMessage",mvo.scope);
			
			if(mvo.scope==EntityMessageVO.SCOPE_SOMEONE){
				doSendEntityToEntityMessage(mvo.toID,mvo);
			}else{
				var dict:Dictionary;
				switch(mvo.scope){
					case EntityMessageVO.SCOPE_ALL:
						dict=this.getVOList();
						break;
					case EntityMessageVO.SCOPE_BY_CATEID:
						dict=this.getVOListByCateID(mvo.toID);
						break;
					case EntityMessageVO.SCOPE_BY_TYPEID:
						dict=this.getVOListByTypeID(mvo.toID);
						break;
				}
				for each(var entVO:EntityVO in dict){
					doSendEntityToEntityMessage(entVO.id,mvo);
				}
				
			}
		}
		
		//这个是优化用的，方便快速的找到某个entityCompFacade
		private var dict_fastEntityFacadeCompMapping:Dictionary;
		private function doSendEntityToEntityMessage(aimEntityID:String,mvo:EntityMessageVO):void{
			//T.p("doSendEntityToEntityMessage",aimEntityID,mvo.name);
			var f:IEntityCompFacade=dict_fastEntityFacadeCompMapping[aimEntityID] as IEntityCompFacade;
			if(f==null){
				
				f=PBE.lookupComponentByType(aimEntityID,IEntityCompFacade) as IEntityCompFacade;
				
				if(f){
					dict_fastEntityFacadeCompMapping[aimEntityID]=f;
				}
			}
			if(f){
				
				f.handleEntityToEntityMessage(mvo);
			}
		}
	}//end of class
}
